﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IRCServer.Entities.Commands;
using IRCServer.Utilities;
using IRCServer.Entities;
using IRCServer.Backend;
using IRC.Utilities;

namespace IRCServer.CommandHandlers
{
    class PRIVMSGCommandHandler : CommandHandlerBase
    {
        public override string HandleCommand(IRCCommandBase command, Session session)
        {
            if (command is PRIVMSGCommand)
            {
                PRIVMSGCommand privmsgCommand = (PRIVMSGCommand)command;

                if (privmsgCommand.Targets == null)
                {
                    return Errors.GetErrorResponse(ErrorCode.ERR_NORECIPIENT, CommandParser.PRIVMSGCommand);
                }

                if (privmsgCommand.Message == null)
                {
                    return Errors.GetErrorResponse(ErrorCode.ERR_NOTEXTTOSEND, string.Empty);
                }

                foreach (string target in privmsgCommand.Targets)
                {
                    List<User> filteredUsers = ServerBackend.Instance.Users.Where(u => u.Nickname.ToLower() == target.ToLower()).ToList();
                    if (filteredUsers.Count == 0)
                    {
                        return Errors.GetErrorResponse(ErrorCode.ERR_NOSUCHNICK, target);
                    }
                    else
                    {
                        List<Session> filteredSessions = Backend.ServerBackend.Instance.ClientSessions.Where(s => s.User == filteredUsers[0]).ToList();

                        if (filteredSessions.Count == 0)
                            throw new Exception("Sessions are corrupted");

                        Session destination = filteredSessions.First();
                        string message = string.Format(":{0} {1} :{2}", session.User.Nickname, CommandParser.PRIVMSGCommand, privmsgCommand.Message);
                        
                        Logger.Instance.Info(string.Format("Sending {0} to {1}", message, target));

                        byte[] messageData = System.Text.Encoding.ASCII.GetBytes(message);
                        destination.Socket.BeginSend(messageData, 0, messageData.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(FinalizeSending), destination);
                    }
                }

                return "OK";
            }
            else
            {
                throw new ArgumentException();
            }
        }

        private void FinalizeSending(IAsyncResult result)
        {
            Session session = (Session)result.AsyncState;
            session.Socket.EndSend(result);
        }
    }
}
